84c219
@@ -17,9 +17,13 @@
 package org.springframework.webflow.validation;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.binding.expression.ExpressionParser;
 import org.springframework.binding.mapping.MappingResults;
@@ -39,6 +43,8 @@
import org.springframework.webflow.execution.RequestContext;
  * A helper class the encapsulates conventions to invoke validation logic.
  * 
  * @author Scott Andrews
+ * @author Canny Duck
+ * @author Jeremy Grelle
  */
 public class ValidationHelper {
 
@@ -76,8 +82,7 @@
public class ValidationHelper {
 	 * @param mappingResults object mapping results
 	 */
 	public ValidationHelper(Object model, RequestContext requestContext, String eventId, String modelName,
-			ExpressionParser expressionParser, MessageCodesResolver messageCodesResolver,
-			MappingResults mappingResults) {
+			ExpressionParser expressionParser, MessageCodesResolver messageCodesResolver, MappingResults mappingResults) {
 		Assert.notNull(model, "The model to validate is required");
 		Assert.notNull(requestContext, "The request context for the validator is required");
 		this.model = model;
@@ -183,8 +188,7 @@
public class ValidationHelper {
 	private boolean invokeValidatorValidateMethodForCurrentState(Object model, Object validator) {
 		String methodName = "validate" + StringUtils.capitalize(requestContext.getCurrentState().getId());
 		// preferred
-		Method validateMethod = ReflectionUtils.findMethod(validator.getClass(), methodName, new Class[] {
-				model.getClass(), ValidationContext.class });
+		Method validateMethod = findValidationMethod(model, validator, methodName, ValidationContext.class);
 		if (validateMethod != null) {
 			if (logger.isDebugEnabled()) {
 				logger.debug("Invoking current state validator method '"
@@ -196,8 +200,7 @@
public class ValidationHelper {
 			return true;
 		}
 		// mvc 2 compatibility only
-		validateMethod = ReflectionUtils.findMethod(validator.getClass(), methodName, new Class[] { model.getClass(),
-				Errors.class });
+		validateMethod = findValidationMethod(model, validator, methodName, Errors.class);
 		if (validateMethod != null) {
 			if (logger.isDebugEnabled()) {
 				logger.debug("Invoking current state validator method '"
@@ -210,8 +213,7 @@
public class ValidationHelper {
 			return true;
 		}
 		// web flow 2.0.0 to 2.0.3 compatibility only [to remove in web flow 3]
-		validateMethod = ReflectionUtils.findMethod(validator.getClass(), methodName, new Class[] { model.getClass(),
-				MessageContext.class });
+		validateMethod = findValidationMethod(model, validator, methodName, MessageContext.class);
 		if (validateMethod != null) {
 			ReflectionUtils.invokeMethod(validateMethod, validator, new Object[] { model,
 					requestContext.getMessageContext() });
@@ -232,8 +234,7 @@
public class ValidationHelper {
 			return true;
 		}
 		// preferred
-		Method validateMethod = ReflectionUtils.findMethod(validator.getClass(), "validate", new Class[] {
-				model.getClass(), ValidationContext.class });
+		Method validateMethod = findValidationMethod(model, validator, "validate", ValidationContext.class);
 		if (validateMethod != null) {
 			if (logger.isDebugEnabled()) {
 				logger.debug("Invoking default validator method '" + ClassUtils.getShortName(validator.getClass())
@@ -244,8 +245,7 @@
public class ValidationHelper {
 			return true;
 		}
 		// mvc 2 compatibility only
-		validateMethod = ReflectionUtils.findMethod(validator.getClass(), "validate", new Class[] { model.getClass(),
-				Errors.class });
+		validateMethod = findValidationMethod(model, validator, "validate", Errors.class);
 		if (validateMethod != null) {
 			if (logger.isDebugEnabled()) {
 				logger.debug("Invoking default validator method '" + ClassUtils.getShortName(validator.getClass())
@@ -258,4 +258,23 @@
public class ValidationHelper {
 		}
 		return false;
 	}
-}
\ No newline at end of file
+
+	private Method findValidationMethod(Object model, Object validator, String methodName, Class context) {
+		Class modelClass = AopUtils.getTargetClass(model);
+
+		List modelSearchClasses = new ArrayList();
+		while (modelClass != null) {
+			modelSearchClasses.add(modelClass);
+			modelClass = modelClass.getSuperclass();
+		}
+		for (Iterator iterator = modelSearchClasses.iterator(); iterator.hasNext();) {
+			Class searchClass = (Class) iterator.next();
+			Method method = ReflectionUtils.findMethod(validator.getClass(), methodName, new Class[] { searchClass,
+					context });
+			if (method != null) {
+				return method;
+			}
+		}
+		return null;
+	}
+}
